﻿// Copyright 2009 William P. Hickey Jr. and William U. Walker
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//     
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//  
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.ComponentModel;

namespace CSReporter
{
    public class Station : INotifyPropertyChanged
    {
        private string callSign;
        private string streetNumber;
        private string streetDirection;
        private string streetName;
        private string cityCode;
        private string stateCode;
        private string crossroad1;
        private string crossroad2;
        private double latitude;
        private double longitude;

        public string CallSign
        {
            get { return callSign; }
            set {
                callSign = value == null ? null : value.Substring(0, Math.Min(value.Length, 10)).Trim().ToUpper();
                this.NotifyPropertyChanged("CallSign");
            }
        }

        public string StreetNumber
        {
            get { return streetNumber; }
            set
            {
                streetNumber = value == null ? null : value.Substring(0, Math.Min(value.Length, 10)).Trim();
                this.NotifyPropertyChanged("StreetNumber");
            }
        }

        public string StreetDirection
        {
            get { return streetDirection; }
            set
            {
                streetDirection = value == null ? null : value.Substring(0, Math.Min(value.Length, 1)).Trim();
                this.NotifyPropertyChanged("StreetDirection");
            }
        }

        public string StreetName
        {
            get { return streetName; }
            set
            {
                streetName = value == null ? null : value.Substring(0, Math.Min(value.Length, 25)).Trim();
                this.NotifyPropertyChanged("StreetName");
            }
        }

        public string CityCode
        {
            get { return cityCode; }
            set
            {
                cityCode = value == null ? null : value.Substring(0, Math.Min(value.Length, 3)).Trim().ToUpper();
                this.NotifyPropertyChanged("CityCode");
            }
        }

        public string StateCode
        {
            get { return stateCode; }
            set
            {
                stateCode = value == null ? null : value.Substring(0, Math.Min(value.Length, 2)).Trim().ToUpper();
                this.NotifyPropertyChanged("StateCode");
            }
        }

        public string Crossroad1
        {
            get { return crossroad1; }
            set
            {
                crossroad1 = value == null ? null : value.Substring(0, Math.Min(value.Length, 25)).Trim();
                this.NotifyPropertyChanged("Crossroad1");
            }
        }

        public string Crossroad2
        {
            get { return crossroad2; }
            set
            {
                crossroad2 = value == null ? null : value.Substring(0, Math.Min(value.Length, 25)).Trim();
                this.NotifyPropertyChanged("Crossroad2");
            }
        }

        public double Latitude
        {
            get { return latitude; }
            set
            {
                latitude = value;
                this.NotifyPropertyChanged("Latitude");
            }
        }

        public double Longitude
        {
            get { return longitude; }
            set
            {
                longitude = value;
                this.NotifyPropertyChanged("Longitude");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }

    public class StationList : BindingList<Station>
    {
        // Static initialization ensures thread safety.
        private static readonly StationList singletonInstance = new StationList();

        private StationList() { }

        public static StationList GetStationList()
        {
            if (singletonInstance.Items.Count == 0)
                singletonInstance.Add(new Station());
            return singletonInstance;
        }

        public bool AddStation(Station station)
        {
            if (Items.Count > 0)
            {
                foreach (Station sta in Items)
                    if (sta.CallSign == station.CallSign)
                        return false;
            }
            Add(station);
            return true;
        }

        public Station GetStation(string callSign)
        {
            foreach (Station station in Items)
            {
                if (station.CallSign == callSign)
                    return station;
            }
            return null;
        }

        public void ReadXml(string fileName)
        {
            if (File.Exists(fileName))
            {
                Clear();
                XmlSerializer deserializer = new XmlSerializer(typeof(List<Station>));
                using (TextReader textReader = new StreamReader(fileName))
                    foreach (Station sta in (List<Station>)deserializer.Deserialize(textReader))
                        Add(sta);
            }
        }

        public void WriteXml(string fileName)
        {
            
            if (Directory.GetParent(fileName).Exists)
            {
                XmlSerializer serializer = new XmlSerializer(typeof(List<Station>));
                using (TextWriter textWriter = new StreamWriter(fileName))
                    serializer.Serialize(textWriter, Items);
            }
        }
    }
}
